home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / OS / ODUtils / Sources / ODNewObj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-08  |  5.0 KB  |  218 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ODNewObj.cpp
  3.  
  4.     Contains:    Abstract wrapper for instantiating objects by class-name
  5.  
  6.     Owned by:    Jens Alfke
  7.  
  8.     Copyright:    © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  9.         
  10. */
  11.  
  12. #ifndef _ODMEMORY_
  13. #include "ODMemory.h"
  14. #endif
  15.  
  16. #ifndef _ODNEWOBJ_
  17. #include "ODNewObj.h"
  18. #endif
  19.  
  20. #ifndef _PLFMDEF_
  21. #include "PlfmDef.h"
  22. #endif
  23.  
  24. #ifndef _EXCEPT_
  25. #include "Except.h"
  26. #endif
  27.  
  28. #ifndef _ODDEBUG_
  29. #include "ODDebug.h"
  30. #endif
  31.  
  32. #ifndef _ODUTILS_
  33. #include <ODUtils.h>
  34. #endif
  35.  
  36. #ifndef _PASCLSTR_
  37. #include <PasclStr.h>
  38. #endif
  39.  
  40. #ifndef _UTILERRS_
  41. #include "UtilErrs.h"
  42. #endif
  43.  
  44. #ifndef __SOM__
  45. #include <som.xh>
  46. #endif
  47.  
  48. #ifndef SOM_SOMClassMgr_xh
  49. #include <somcm.xh>
  50. #endif
  51.  
  52.  
  53. #ifdef _PLATFORM_MACINTOSH_
  54.  
  55.     #ifndef __STRINGS__
  56.     #include <strings.h>
  57.     #endif
  58.     
  59.     #include <CodeFragments.h>
  60.     
  61.     #define LOAD_UNDER_ASSUMED_NAME   1
  62.     /*    SOM requires that the library name (in the 'cfrg') be of the form "Module::ClassName".
  63.         This obviously won't match the library's SYM file name. This causes problems for source
  64.         level debuggers; they can't associate the two and you end up not being able to debug
  65.         the library.
  66.         To work around this, we give the library two names (two 'cfrg' entries), the second of
  67.         which is just the classname. Then if the SYM file name matches the classname, we can first
  68.         load the library by the classname, which will signal the debugger that it can link the
  69.         library up with the similarly-named SYM file.
  70.         Got that?? Off we go!!
  71.     */
  72. #endif
  73.  
  74. #ifndef _ODDEBUG_
  75. #include "ODDebug.h"
  76. #endif
  77.  
  78.  
  79. const ODSize kMinAppFreeSpace =        48 * 1024;
  80. const ODSize kMinAppContigSpace =     8 * 1024;
  81.  
  82. static somTD_SOMError            *gOld_SOMError;
  83.  
  84.  
  85. extern "C" {
  86.     static void
  87.     Temp_GetClass_SOMError( int error, corbastring filename, int linenum );
  88. }
  89.  
  90.  
  91. static void
  92. Temp_GetClass_SOMError( int error, corbastring filename, int linenum )
  93. {
  94.     int severity = error % 10;
  95.     if( severity == SOM_Fatal ) {
  96.         WARN("Fatal SOM err %d caught during GetClass; throwing...",error);
  97.         THROW(error);
  98.     } else if( gOld_SOMError )
  99.         gOld_SOMError(error,filename,linenum);
  100. }
  101.  
  102.  
  103. static SOMClass*
  104. GetClass( const char *className )
  105. {
  106.     ODRequireFreeSpace(kMinAppFreeSpace,kMinAppContigSpace,kODTrue);
  107.     
  108.     char libname[64];
  109.  
  110. #if LOAD_UNDER_ASSUMED_NAME
  111.     // First grab everything after the last colon in className:
  112.     const char *lastcolon = strrchr(className,':');
  113.     if (lastcolon == nil) {
  114.         // Hack to load Bento:
  115.         if( strcmp(className,"ODFileContainer")==0 ||
  116.             strcmp(className,"ODMemContainer")==0 ||
  117.             strcmp(className,"ODEmbeddedContainer")==0 )
  118.                 strcpy(libname, "OpenDoc Bento");
  119.         else
  120.                 strcpy(libname, className);
  121.     }
  122.     else {
  123.         strncpy(libname,lastcolon+1,sizeof(libname)-1);
  124.         libname[sizeof(libname)-1] = '\0';
  125.     }
  126. #else
  127.     strcpy(libname,className);
  128. #endif /*LOAD_UNDER_ASSUMED_NAME*/
  129.     
  130.     c2pstr(libname);
  131.  
  132.     CFragConnectionID connID;
  133.     Ptr mainAddr;
  134.     Str255 errName;
  135.     
  136.     // First see if the library is already loaded:
  137.     OSErr err = GetSharedLibrary((StringPtr)libname, kCurrentCFragArch,
  138.                                 kFindCFrag, &connID,&mainAddr,errName);
  139.                                 
  140.     if( err == fragLibNotFound || err==fragLibConnErr ) {
  141.         // Nope, need to load it:
  142.         err = GetSharedLibrary((StringPtr)libname, kCurrentCFragArch,
  143.                                     kLoadCFrag, &connID,&mainAddr,errName);
  144.         if( err==noErr && !ODHaveFreeSpace(kMinAppFreeSpace,
  145.                                            kMinAppContigSpace,kODTrue) ) {
  146.             CloseConnection(&connID);
  147.             err = fragNoMem;
  148. #if ODDebug
  149.             CopyPascalString(errName,"\pOD free space too low");
  150. #endif
  151.         }
  152.     }
  153.  
  154.     if( err ) {
  155.         p2cstr(errName);
  156.         WARN("Can't load lib '%s'; error %hd, '%s'",
  157.                 p2cstr((StringPtr)libname),err,errName);
  158.         THROW(err,(char*)errName);
  159.     }
  160.     
  161.     /* Now try to load the class. Install a temporary error handler that
  162.         converts a fatal SOM error into a THROW, in case SOM runs out of
  163.         memory. */
  164.     SOMClass *c;
  165.     gOld_SOMError = SOMError;
  166.     SOMError = &Temp_GetClass_SOMError;
  167.     TRY{
  168.         long majorVersion = 0;
  169.         long minorVersion = 0;
  170.         somId id = somIdFromString((corbastring)className);
  171.         c = somGetDynamicClassReference(id,majorVersion,minorVersion, kODNULL);
  172.         SOMFree(id);
  173.     }CATCH_ALL{
  174.         SOMError = gOld_SOMError;
  175.         RERAISE;
  176.     }ENDTRY
  177.     SOMError = gOld_SOMError;
  178.         
  179.     
  180.     if( !c )
  181.         THROW(kODErrCantLoadSOMClass);
  182.     return c;
  183. }
  184.  
  185.  
  186. SOMObject*
  187. ODNewObject( const char *className )
  188. {
  189.     SOMClass *cls = GetClass(className);
  190.     THROW_IF_NULL (cls);  // would have thrown anyway...
  191.     SOMObject* obj = cls->somNew();
  192.     somReleaseClassReference(cls); // must release class reference
  193.     THROW_IF_NULL (obj); // similar to new ODObject, must throw if nil
  194.     return obj;
  195. }
  196.  
  197.  
  198. ODBoolean
  199. ODClassExists( const char *className )
  200. {
  201.     /* This function will now propagate errors if the library _does_ exist
  202.        but just couldn't be loaded due to e.g. insufficient memory or missing
  203.        imports. This allows for better error display to the user since otherwise
  204.        the error would be eaten and replaced with a simple Boolean return value. */
  205.     
  206.     ODBoolean result = kODTrue;
  207.     TRY
  208.         SOMClass *cls = GetClass(className);
  209.         somReleaseClassReference ( cls );
  210.     CATCH_ALL
  211.         if( ErrorCode()==kODErrCantLoadSOMClass || ErrorCode()==fragLibNotFound )
  212.             result = kODFalse;
  213.         else
  214.             RERAISE;
  215.     ENDTRY
  216.     return result;
  217. }
  218.